package com.smit.dvb.jni;

import com.smit.adapter.DVBAdapter;
import com.smit.adapter.DVBDataManager;
import com.smit.dvb.CIData;
import com.smit.dvb.CIMenuInfo;
import com.smit.dvb.CIPinInfo;
import com.smit.dvb.DVBEitInfo;
import com.smit.dvb.DVBFilterParam;
import com.smit.dvb.DVBFreqInfo;
import com.smit.dvb.DVBNetworkInfo;
import com.smit.dvb.DVBServiceInfo;
import com.smit.dvb.DVBTimeInfo;
import com.smit.dvb.DVBTunerInfo;
import com.smit.dvb.IDVBCallback;
import com.smit.dvb.scan.ScanControl;
import com.smit.dvb.system.SystemControl;
import com.smit.dvb.update.UpdateControl;
import com.smit.utils.LogUtil;

/**
 * DVB jni对应接口，对接底层c代码
 */
public final class DVB {
    private static final String TAG = "DVB";
    private boolean bDVBInitOk = false;
    private IDVBCallback dvbCallback;

    private DVB() {

    }

    /**
     * 获取对象实例
     * @return DVB对象单例
     */
    public static DVB getInstance() {
        return SingletonHolder.instance;
    }

    /**
     * 获取DVB是否初始化成功
     * @return DVB对象单例
     */
    public boolean isbDVBInitOk() {
        return bDVBInitOk;
    }

    /**
     * jni消息回调
     * @param type 消息类型
     * @param msg 消息值
     * @param param 消息参数
     */
    void jniDVBCallback(int type, int msg, Object param) {
        LogUtil.error(TAG, "jniDVBCallback handle callback type=" + type + " msg=" + msg);
        if (type == IDVBCallback.DVB_CB_TYPE_SYSTEM && msg == SystemControl.MSG_SYSTEM_INIT_OK) {
            bDVBInitOk = true;
        }
        if (dvbCallback == null) {
            LogUtil.error(TAG, "jniDVBCallback dvbCallback is null");
            return;
        }
        if (type == IDVBCallback.DVB_CB_TYPE_SCAN && msg == ScanControl.MSG_SCAN_DVB_NETWORK) {
            DVBNetworkInfo networkInfo = (DVBNetworkInfo) param;
            DVBDataManager dvbDataManager = DVBAdapter.getInstance().getDVBDataManager();
            if (dvbDataManager != null && networkInfo != null) {
                LogUtil.info(TAG, "MSG_SCAN_DVB_NETWORK name=" + networkInfo.networkName
                        + " id=" + networkInfo.networkId);
                dvbDataManager.loadPluginLib(networkInfo.networkName);
            }
        }
        switch (type) {
            case IDVBCallback.DVB_CB_TYPE_CI:
                dvbCallback.handleCICallbackMsg(msg, param);
                break;
            case IDVBCallback.DVB_CB_TYPE_EPG:
                dvbCallback.handleEpgCallbackMsg(msg, param);
                break;
            case IDVBCallback.DVB_CB_TYPE_SCAN:
                dvbCallback.handleScanCallbackMsg(msg, param);
                if (msg == ScanControl.MSG_SCAN_START) {
                 dvbCallback.handleUpdateCallbackMsg(UpdateControl.MSG_UPDATE_REQUEST_FIRMWARE, "00ff002020000000");
                }
                break;
            case IDVBCallback.DVB_CB_TYPE_SERVICE:
                dvbCallback.handleServiceCallbackMsg(msg, param);
                break;
            case IDVBCallback.DVB_CB_TYPE_SETUP:
                dvbCallback.handleSetupCallbackMsg(msg, param);
                break;
            case IDVBCallback.DVB_CB_TYPE_SYSTEM:
                dvbCallback.handleSystemCallbackMsg(msg, param);
                break;
            case IDVBCallback.DVB_CB_TYPE_UPDATE:
                dvbCallback.handleUpdateCallbackMsg(msg, param);
                break;
            default:
                LogUtil.error(TAG, "jniDVBCallback in default case type=" + type);
                break;
        }
    }

    /**
     * 注册回调接口
     * @param callback 回调接口
     */
    public void registerDVBCallback(IDVBCallback callback) {
        dvbCallback = callback;
    }

    /**
     * 取消回调接口
     */
    public void removeDVBCallback() {
        dvbCallback = null;
    }

    /**** system control ****/
    /**
     * 初始化DVB系统
     * @return 0 成功，其他失败
     */
    public native int initialize();

    /**
     * 唤醒DVB系统
     */
    public native void resume();

    /**
     * DVB进入待机
     */
    public native void standby();

    /**
     * 结束DVB系统
     * @return 0成功，其他失败
     */
    public native int terminate();

    /**
     * 设备插入拔出通知
     * @param status 0拔出，1插入
     * @param fd 设备的fd
     */
    public native void deviceStatusChanged(byte status, int fd);

    /**** setup control ***/
    /**
     * 设置频点表
     * @param freqTable 频点表
     */
    public native void setFrequencyTable(DVBFreqInfo[] freqTable);

    /**
     * 设置插件文件路径
     * @param pluginPath 文件全路径
     */
    public native void setDVBPluginPath(String pluginPath);

    /**
     * 设置节目分组ID
     * @param groupId 分组ID
     */
    public native void setServiceGroupId(int groupId);

    /**
     * 获取节目分组ID
     * @return 分组ID
     */
    public native int getServiceGroupId();

    /**
     * 恢复默认设置
     */
    public native void restoreSettings();

    /**
     * 获取DVB系统的时间，码流中的时间
     * @return DVB系统的时间
     */
    public native DVBTimeInfo getDVBTime();

    /**
     * 获取EIT信息
     * @param serviceInfo 节目信息
     * @param type 0当前，1下一个
     * @return 节目EIT信息
     */
    public native DVBEitInfo getEitInfo(DVBServiceInfo serviceInfo, int type);

     /**
     * 获取多天的EIT信息
     * @param serviceInfo 节目信息
     * @return 节目EIT信息数组
     */
    public native DVBEitInfo[] getScheduleInfo(DVBServiceInfo serviceInfo);

    /**
     * 获取当前分组下所有节目信息
     * @return 所有节目信息
     */
    public native DVBServiceInfo[] getAllServices();

    /**
     * 手动锁台
     * @param tunerInfo tuner参数
     * @return 0锁台成功，其他锁台失败
     */
    public native int manualTune(DVBTunerInfo tunerInfo);

    /**
     * 获取 tuner状态
     * @param block true底层实时获取然后返回, false底层直接返回上次更新的状态
     * @return tuner信息
     */
    public native DVBTunerInfo getTunerStatus(boolean block);

    /**
     * 开始导入频道列表
     */
    public native void startImportServices();

    /**
     * 导入频道列表
     * @param services 节目信息
     * @param count 节目数
     * @param groupId 分组Id
     * @param groupName 分组名
     * @return 导入成功节目数
     */
    public native int importServices(DVBServiceInfo[] services, int count, int groupId, String groupName);

    /**
     * 导入结束
     */
    public native void finishImportServices();


    /*** scan control ***/
    /**
     * 手动搜台
     * @param tunerInfo tuner参数
     * @return 0成功，其他失败
     */
    public native int manualScan(DVBTunerInfo tunerInfo);

    /**
     * 自动搜台
     * @param startFreq 开始频点
     * @param endFreq 结束频点
     * @return 0成功，其他失败
     */
    public native int autoScan(int startFreq, int endFreq);

    /**
     * 全频点搜台
     * @param startFreq 开始频点
     * @param endFreq 结束频点
     * @return 0成功，其他失败
     */
    public native int fullScan(int startFreq, int endFreq);

    /**
     * 取消搜台
     */
    public native void abortScan();


    /*** service control ***/
    /**
     * 播放指定的节目
     * @param index 节目索引号
     * @return 0成功，其他失败
     */
    public native int playServiceByIndex(int index);

    /**
     * 关闭播放服务
     */
    public native void stopDVBService();

    /*** ci control ***/

    /**
     * 打开CI会话
     */
    public native void openSession();

    /**
     * 关闭CI会话
     */
    public native void closeSession();

    /**
     * 选择CI Menu item
     * @param index item索引
     */
    public native void selectMenuItem(int index);

    /**
     * 设置MMI pin码
     * @param pin 密码
     */
    public native void setPin(String pin);

    /**
     * 获取CI Menu 显示信息
     * @return CIMenuInfo对象
     */
    public native CIMenuInfo getCIMenuInfo();

    /**
     * 获取CI Pin 信息
     * @return CIPinInfo 对象
     */
    public native CIPinInfo getCIPinInfo();

    /**
     * 获取hardware信息
     * @return hardware信息字符串
     */
    public native CIData getHardwareInfo();

    /**
     * 获取SmartCard相关信息
     * @return SmartCard相关信息字符串
     */
    public native CIData getSmartCardInfo();

    /**
     * 获取设备Type信息
     * @return 设备Type信息字符串
     */
    public native CIData getDeviceType();

    /**
     * 获取设备ID信息
     * @return 设备ID信息字符串
     */
    public native CIData getDeviceId();

    /**
     * 当tsId 和tsName相同时的区别码
     * @return 区别码
     */
    public native int getMagicId();

    /**
     * 设置固件信息到底层
     * @param sn 序列号
     * @param filePath 固件路径
     */
    public native void setFirmwareInfo(String sn, String filePath);
//    public void setFirmwareInfo(String sn, String filePath)
//    {
//        LogUtil.debug(TAG, " setFirmwareInfo sn=" + sn + " filePath=" + filePath);
//    }

    /**
     * 过滤器开启成功后返回
     * @param param 过滤参数
     * @return filterId
     */
    public native int startDmxFilter(DVBFilterParam param);

    /**
     * 停止过滤
     * @param filterId 过滤id
     * @return 0成功，其他失败
     */
    public native int stopDmxFilter(int filterId);

    /**
     * 该函数被底层JNI调用，JNI接收到上层要求的数据后会调用本函数通知应用
     * @param filterId 过滤id
     * @param data 数据
     * @return 0成功，其他失败
     */
    public int jniDmxCallBack(int filterId, byte[] data)
    {
        return 0;
    }

    private static class SingletonHolder {
        private static DVB instance = new DVB();
    }
}

